/* ipRouteNodeLib.h - public routines for the IP routing information base */

/* Copyright 1984 - 2005 Wind River Systems, Inc. */

/*
modification history
--------------------
01g,24feb05,spm  performance updates and code cleanup (SPR #100995)
01f,28may04,niq  Merging from base6 label POST_ITER5_FRZ16_REBASE
01e,10nov03,cdw  Rebase from base6 iteration 1 view
01d,04nov03,rlm  Ran batch header path update for header re-org.
01c,15sep03,vvv  updated path for new headers
01b,15oct02,niq  pass the Cookie argument to the lock/unlock calls
01a,09aug02,spm  written
*/

/*
DESCRIPTION
This file defines the route entry dispatch table for an implementation
of the Routing Information Base component that supports IP. All RIB 
implementations must use this dispatch table definition to supply the
required route operations.

The IP RIB organizes route entries into RIB nodes according to the
destination address and netmask values. Each RIB node stores a common
copy of those two values for all attached routes.

This file defines macros to use the routines in the dispatch table and
to retrieve the common data without introducing symbolic dependencies on
any internal data types. The IP Routing Table Manager is the only component
permitted to use the macros defined in this file.
*/

#ifndef _INCipRouteNodeLibh
#define _INCipRouteNodeLibh

#ifdef __cplusplus
extern "C" {
#endif

#include "semLib.h"
#include <sys/socket.h>  
#include <route/ipRouteNodeData.h>

struct ipRouteDispatchTable
    {
    struct ipRibHead *    (* ribCreate) (ULONG routeFormat);
    STATUS    (* ribDestroy) (struct ipRibHead * pRibHead);
    struct ipRouteNode *  (* ribNodeAdd) (struct ipRibHead * pRibHead, 
					  struct sockaddr * pDstAddr, 
					  struct sockaddr * pNetmask, 
					  void * pRouteEntry, int * pNew);
    STATUS    (* ribNodeDelete) (struct ipRibHead * pRibHead,
                                 struct ipRouteNode * pRibNode);
    struct ipRouteNode *  (* ribNodeBestMatch) (struct ipRibHead * pRibHead,
                                         struct sockaddr * pDstAddr);
    struct ipRouteNode *  (* ribNodeExactMatch) (struct ipRibHead * pRibHead, 
						 struct sockaddr * pDstAddr, 
						 struct sockaddr * pNetmask);
    struct ipRouteNode *  (* ribNodeLessSpecGet) (struct ipRibHead * pRibHead,
                                              struct ipRouteNode * pRibNode);
    struct ipRouteNode *  (* ribNodeLexNextGet) (struct ipRibHead * pRibHead, 
						 struct sockaddr * pDstAddr, 
						 struct sockaddr * pNetmask, 
						 ULONG indexType);
    struct ipRouteNode *  (* ribNodeLexNextRepeat)
                                            (struct ipRibHead * pRibHead,
                                              struct ipRouteNode * pRibNode);
    STATUS    (* ribLock) (struct ipRibHead * pRibHead, int lockType);
    STATUS    (* ribUnlock) (struct ipRibHead * pRibHead, int lockType);
    };

struct ipRibHead
    {
    struct ipRouteDispatchTable * pIpRouteDispatchTable;
    SEM_ID readLock1; 	/*
                         * mutual exclusion for basic operations:
                         *    add, delete, modify, and isolated lookup.
                         */

    SEM_ID readLock2; 	/* mutual exclusion for table traversal */
    };

typedef struct ipRibHead * IP_RIB_ID;

/* Macros for data items: see ipRouteNode structure */

#define RIB_IPADDR_GET(pRibNode)  (pRibNode->pDest)

#define RIB_NETMASK_GET(pRibNode)  (pRibNode->pNetmask)

#define RIB_RTM_ENTRY_GET(pRibNode)     (pRibNode->pRtmEntry)

#define RIB_RTM_ENTRY_SET(pRibNode, pRtEntry) \
                                        (pRibNode->pRtmEntry = pRtEntry)

/* Macro for RIB creation/setup: sole use of different type for functions */

#define RIB_CREATE(pIpRouteDispatchTable, routeFormat) \
            (pIpRouteDispatchTable->ribCreate (routeFormat))

#define RIB_DESTROY(pRibCookie) \
    ( ((struct ipRibHead *) (pRibCookie))->pIpRouteDispatchTable-> \
           ribDestroy (pRibCookie))

/* Macros for route operations: see dispatch table */

#define RIB_NODE_ADD(pRibCookie, pDstAddr, pNetmask, pRouteEntry, pNew) \
    ( ((struct ipRibHead *) (pRibCookie))->pIpRouteDispatchTable-> \
           ribNodeAdd (pRibCookie, pDstAddr, pNetmask, pRouteEntry, pNew))

#define RIB_NODE_DELETE(pRibCookie, pIpRouteNode) \
    ( ((struct ipRibHead *) (pRibCookie))->pIpRouteDispatchTable-> \
           ribNodeDelete (pRibCookie, pIpRouteNode))

#define RIB_NODE_BEST_MATCH(pRibCookie, pDstAddr) \
    ( ((struct ipRibHead *) (pRibCookie))->pIpRouteDispatchTable-> \
           ribNodeBestMatch (pRibCookie, pDstAddr))

#define RIB_NODE_EXACT_MATCH(pRibCookie, pDstAddr, pNetmask) \
    ( ((struct ipRibHead *) (pRibCookie))->pIpRouteDispatchTable-> \
           ribNodeExactMatch (pRibCookie, pDstAddr, pNetmask))

#define RIB_NODE_LESS_SPEC_GET(pRibCookie, pIpRouteNode) \
    ( ((struct ipRibHead *) (pRibCookie))->pIpRouteDispatchTable-> \
           ribNodeLessSpecGet (pRibCookie, pIpRouteNode))

#define RIB_NODE_LEX_NEXT_GET(pRibCookie, pDstAddr, pNetmask, indexType) \
    ( ((struct ipRibHead *) (pRibCookie))->pIpRouteDispatchTable-> \
           ribNodeLexNextGet (pRibCookie, pDstAddr, pNetmask, indexType))

#define RIB_NODE_LEX_NEXT_REPEAT(pRibCookie, pIpRouteNode) \
    ( ((struct ipRibHead *) (pRibCookie))->pIpRouteDispatchTable-> \
           ribNodeLexNextRepeat (pRibCookie, pIpRouteNode))

#define RIB_LOCK(pRibCookie, lockType) \
    ( ((struct ipRibHead *) (pRibCookie))->pIpRouteDispatchTable-> \
                                                 ribLock (pRibCookie, lockType))

#define RIB_UNLOCK(pRibCookie, lockType) \
    ( ((struct ipRibHead *) (pRibCookie))->pIpRouteDispatchTable-> \
                                              ribUnlock (pRibCookie, lockType))

/* Values for parameters of registered routines */

#define RIB_LOCK_1        1  /* First read lock: for "standard" searches */
#define RIB_LOCK_2        2  /* Second read lock: for lexical searches */
#define RIB_DUAL_LOCK     3  /* Obtain both locks for add/delete operations */

#define RIB_FORMAT_IPV4   4  /* IPv4 routes: 4 byte address/4 byte netmask */
#define RIB_FORMAT_IPV6   6  /* IPv6 routes: 16 byte address/1 byte prefix */

#define ROUTE_MIB_1213    1  /* RFC 1213 MIB: address is only index value */
#define ROUTE_MIB_2096    2  /* RFC 2096 MIB: netmask is available as index */

#ifdef __cplusplus
}
#endif

#endif /* _INCipRouteNodeLibh */
